package com.lcm.weam.entity.algo;

import lombok.Data;
import lombok.ToString;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;

/**
 * 地表水评价实体类
 */
@Data
@ToString
public class SurfaceWaterEva {
    //信息
    private String name; //名称
    private String type; //类型
    private Integer baseLevel; //标准 0 1 2 3 4
    //24基础指标
    private Double temperature; //水温
    private Double pH; //pH
    private Double DO; //溶解氧
    private Double permanganateIndex; //高猛酸盐指数
    private Double COD; //化学需氧量
    private Double BOD5; //五日生物需氧量
    private Double NH3N; //氨氮
    private Double TP; //总磷
    private Double TN; //总氮
    private Double Cu; //铜
    private Double Zn; //锌
    private Double F; //氟化物
    private Double Se; //硒
    private Double As; //砷
    private Double Hg; //汞
    private Double Cd; //镉
    private Double Cr; //铬
    private Double Pb; //铅
    private Double cyan; //氰化物
    private Double volatilePhenol; //挥发酚
    private Double petroleum; //石油类
    private Double anionics; //阴离子表面活性剂
    private Double S; //硫化物
    private Double fecalColiform; //粪大肠菌群
    //结果
    private Integer level; //评级：0 1 2 3 4 5
    private Map<String, Double> singleValue; //单因子指标
    private Double mutiValue; //综合评价值

    //计算结果的方法
    public void doEva() {
        Map<String, Double> map = new Hashtable<>();//赋给单因子
        int levelRes = 0; //赋给评级
        List<Double> valueList = new ArrayList<>();//赋给用于计算value
        double value = 0.0; //赋给综合评价值
        //下面是计算
        if (pH != null){
            double pHValue = 0.0;
            if (pH > 7.0){
                pHValue = (pH-7.0)/2;
                map.put("pH值", Math.round(pHValue*1000)*0.001d);
                valueList.add(pHValue);
            }else{
                pHValue = 7.0-pH;
                map.put("pH值", Math.round(pHValue*1000)*0.001d);
                valueList.add(pHValue);
            }
        }
        if (DO != null){
            double DOstand = Standard1.Standard_DO[baseLevel];
            double DOValue = 0.0;
            if (DO < DOstand){
                DOValue = 10.0-9.0*(DO/DOstand);
                map.put("溶解氧", Math.round(DOValue*1000)*0.001d);
                valueList.add(DOValue);
            }else{
                double DOf = 0.0;
                if (temperature != null){
                    DOf = 468/(31.6+temperature);
                }else{
                    DOf = 468/(31.6+25);
                }
                DOValue = Math.abs(DOf-DO)/(DOf-DOstand);
                map.put("溶解氧", Math.round(DOValue*1000)*0.001d);
                valueList.add(DOValue);
            }
            for (int i = 0; i < 5; i++) {
                if (DO >= Standard1.Standard_DO[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && DO < Standard1.Standard_DO[i]){
                    levelRes = 5;
                }
            }
        }
        if (permanganateIndex != null){
            double permanganateIndexStand = Standard1.Standard_permanganateIndex[baseLevel];
            double permanganateIndexValue = permanganateIndex/permanganateIndexStand;
            map.put("高锰酸盐指数", Math.round(permanganateIndexValue*1000)*0.001d);
            valueList.add(permanganateIndexValue);
            for (int i = 0; i < 5; i++) {
                if (permanganateIndex <= Standard1.Standard_permanganateIndex[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && permanganateIndex > Standard1.Standard_permanganateIndex[i]){
                    levelRes = 5;
                }
            }
        }
        if (COD != null){
            double CODStand = Standard1.Standard_COD[baseLevel];
            double CODValue = COD/CODStand;
            map.put("化学需氧量（COD）", Math.round(CODValue*1000)*0.001d);
            valueList.add(CODValue);
            for (int i = 0; i < 5; i++) {
                if (COD <= Standard1.Standard_COD[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && COD > Standard1.Standard_COD[i]){
                    levelRes = 5;
                }
            }
        }
        if (BOD5 != null){
            double BOD5Stand = Standard1.Standard_BOD5[baseLevel];
            double BOD5Value = BOD5/BOD5Stand;
            map.put("五日生化需氧量（BOD5）", Math.round(BOD5Value*1000)*0.001d);
            valueList.add(BOD5Value);
            for (int i = 0; i < 5; i++) {
                if (BOD5 <= Standard1.Standard_BOD5[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && BOD5 > Standard1.Standard_BOD5[i]){
                    levelRes = 5;
                }
            }
        }
        if (NH3N != null){
            double NH3NStand = Standard1.Standard_NH3N[baseLevel];
            double NH3NValue = NH3N/NH3NStand;
            map.put("氨氮（NH3-N）", Math.round(NH3NValue*1000)*0.001d);
            valueList.add(NH3NValue);
            for (int i = 0; i < 5; i++) {
                if (NH3N <= Standard1.Standard_NH3N[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && NH3N > Standard1.Standard_NH3N[i]){
                    levelRes = 5;
                }
            }
        }
        if (TP != null){
            if (type.equals("湖库型")){
                double TPStand = Standard1.Standard_TP2[baseLevel];
                double TPValue = TP/TPStand;
                map.put("总磷（以P计）", Math.round(TPValue*1000)*0.001d);
                valueList.add(TPValue);
                for (int i = 0; i < 5; i++) {
                    if (TP <= Standard1.Standard_TP2[i]){
                        levelRes = Math.max(i, levelRes);
                        break;
                    }
                    if (i==4 && TP > Standard1.Standard_TP2[i]){
                        levelRes = 5;
                    }
                }
            }else {
                double TPStand = Standard1.Standard_TP1[baseLevel];
                double TPValue = TP/TPStand;
                map.put("总氮（湖、库，以N计）", Math.round(TPValue*1000)*0.001d);
                valueList.add(TPValue);
                for (int i = 0; i < 5; i++) {
                    if (TP <= Standard1.Standard_TP1[i]){
                        levelRes = Math.max(i, levelRes);
                        break;
                    }
                    if (i==4 && TP > Standard1.Standard_TP1[i]){
                        levelRes = 5;
                    }
                } 
            }

        }
        if (TN != null){
            double TNStand = Standard1.Standard_TN[baseLevel];
            double TNValue = TN/TNStand;
            map.put("总氮（湖、库，以N计）", Math.round(TNValue*1000)*0.001d);
            valueList.add(TNValue);
            for (int i = 0; i < 5; i++) {
                if (TN <= Standard1.Standard_TN[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && TN > Standard1.Standard_TN[i]){
                    levelRes = 5;
                }
            }
        }
        if (Cu != null){
            double CuStand = Standard1.Standard_Cu[baseLevel];
            double CuValue = Cu/CuStand;
            map.put("铜", Math.round(CuValue*1000)*0.001d);
            valueList.add(CuValue);
            for (int i = 0; i < 5; i++) {
                if (Cu <= Standard1.Standard_Cu[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && Cu > Standard1.Standard_Cu[i]){
                    levelRes = 5;
                }
            }
        }
        if (Zn != null){
            double ZnStand = Standard1.Standard_Zn[baseLevel];
            double ZnValue = Zn/ZnStand;
            map.put("锌", Math.round(ZnValue*1000)*0.001d);
            valueList.add(ZnValue);
            for (int i = 0; i < 5; i++) {
                if (Zn <= Standard1.Standard_Zn[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && Zn > Standard1.Standard_Zn[i]){
                    levelRes = 5;
                }
            }
        }
        if (F != null){
            double FStand = Standard1.Standard_F[baseLevel];
            double FValue = F/FStand;
            map.put("氟化物（以Fˉ计）", Math.round(FValue*1000)*0.001d);
            valueList.add(FValue);
            for (int i = 0; i < 5; i++) {
                if (F <= Standard1.Standard_F[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && F > Standard1.Standard_F[i]){
                    levelRes = 5;
                }
            }
        }
        if (Se != null){
            double SeStand = Standard1.Standard_Se[baseLevel];
            double SeValue = Se/SeStand;
            map.put("硒", Math.round(SeValue*1000)*0.001d);
            valueList.add(SeValue);
            for (int i = 0; i < 5; i++) {
                if (Se <= Standard1.Standard_Se[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && As > Standard1.Standard_As[i]){
                    levelRes = 5;
                }
            }
        }
        if (As != null){
            double AsStand = Standard1.Standard_As[baseLevel];
            double AsValue = As/AsStand;
            map.put("砷", Math.round(AsValue*1000)*0.001d);
            valueList.add(AsValue);
            for (int i = 0; i < 5; i++) {
                if (As <= Standard1.Standard_As[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && As > Standard1.Standard_As[i]){
                    levelRes = 5;
                }
            }
        }
        if (Hg != null){
            double HgStand = Standard1.Standard_Hg[baseLevel];
            double HgValue = Hg/HgStand;
            map.put("汞", Math.round(HgValue*1000)*0.001d);
            valueList.add(HgValue);
            for (int i = 0; i < 5; i++) {
                if (Hg <= Standard1.Standard_Hg[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && Hg > Standard1.Standard_Hg[i]){
                    levelRes = 5;
                }
            }
        }
        if (Cd != null){
            double CdStand = Standard1.Standard_Cd[baseLevel];
            double CdValue = Cd/CdStand;
            map.put("镉", Math.round(CdValue*1000)*0.001d);
            valueList.add(CdValue);
            for (int i = 0; i < 5; i++) {
                if (Cd <= Standard1.Standard_Cd[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && Cd > Standard1.Standard_Cd[i]){
                    levelRes = 5;
                }
            }
        }
        if (Cr != null){
            double CrStand = Standard1.Standard_Cr[baseLevel];
            double CrValue = Cr/CrStand;
            map.put("铬（六价）", Math.round(CrValue*1000)*0.001d);
            valueList.add(CrValue);
            for (int i = 0; i < 5; i++) {
                if (Cr <= Standard1.Standard_Cr[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && Cr > Standard1.Standard_Cr[i]){
                    levelRes = 5;
                }
            }
        }
        if (Pb != null){
            double PbStand = Standard1.Standard_Pb[baseLevel];
            double PbValue = Math.round(Pb/PbStand*1000)*0.001d;
            map.put("铅", PbValue);
            valueList.add(PbValue);
            for (int i = 0; i < 5; i++) {
                if (Pb <= Standard1.Standard_Pb[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && Pb > Standard1.Standard_Pb[i]){
                    levelRes = 5;
                }
            }
        }
        if (cyan != null){
            double cyanStand = Standard1.Standard_cyan[baseLevel];
            double cyanValue = cyan/cyanStand;
            map.put("氰化物", Math.round(cyanValue*1000)*0.001d);
            valueList.add(cyanValue);
            for (int i = 0; i < 5; i++) {
                if (cyan <= Standard1.Standard_cyan[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && cyan > Standard1.Standard_cyan[i]){
                    levelRes = 5;
                }
            }
        }
        if (volatilePhenol != null){
            double volatilePhenolStand = Standard1.Standard_volatilePhenol[baseLevel];
            double volatilePhenolValue = volatilePhenol/volatilePhenolStand;
            map.put("挥发酚", Math.round(volatilePhenolValue*1000)*0.001d);
            valueList.add(volatilePhenolValue);
            for (int i = 0; i < 5; i++) {
                if (volatilePhenol <= Standard1.Standard_volatilePhenol[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && volatilePhenol > Standard1.Standard_volatilePhenol[i]){
                    levelRes = 5;
                }
            }
        }
        if (petroleum != null){
            double petroleumStand = Standard1.Standard_petroleum[baseLevel];
            double petroleumValue = petroleum/petroleumStand;
            map.put("石油类", Math.round(petroleumValue*1000)*0.001d);
            valueList.add(petroleumValue);
            for (int i = 0; i < 5; i++) {
                if (petroleum <= Standard1.Standard_petroleum[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && petroleum > Standard1.Standard_petroleum[i]){
                    levelRes = 5;
                }
            }
        }
        if (anionics != null){
            double anionicsStand = Standard1.Standard_anionics[baseLevel];
            double anionicsValue = anionics/anionicsStand;
            map.put("阴离子表面活性剂", Math.round(anionicsValue*1000)*0.001d);
            valueList.add(anionicsValue);
            for (int i = 0; i < 5; i++) {
                if (anionics <= Standard1.Standard_anionics[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && anionics > Standard1.Standard_anionics[i]){
                    levelRes = 5;
                }
            }
        }
        if (S != null){
            double SStand = Standard1.Standard_S[baseLevel];
            double SValue = S/SStand;
            map.put("硫化物", Math.round(SValue*1000)*0.001d);
            valueList.add(SValue);
            for (int i = 0; i < 5; i++) {
                if (S <= Standard1.Standard_S[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && S > Standard1.Standard_S[i]){
                    levelRes = 5;
                }
            }
        }
        if (fecalColiform != null){
            double fecalColiformStand = Standard1.Standard_fecalColiform[baseLevel];
            double fecalColiformValue = fecalColiform/fecalColiformStand;
            map.put("粪大肠菌群（个/L）", Math.round(fecalColiformValue*1000)*0.001d);
            valueList.add(fecalColiformValue);
            for (int i = 0; i < 5; i++) {
                if (fecalColiform <= Standard1.Standard_fecalColiform[i]){
                    levelRes = Math.max(i, levelRes);
                    break;
                }
                if (i==4 && fecalColiform > Standard1.Standard_fecalColiform[i]){
                    levelRes = 5;
                }
            }
        }
        //计算综合，赋值
        if (!valueList.isEmpty()){
            Double sum = 0.0;
            for (Double aDouble : valueList) {
                sum += aDouble;
            }
            value = sum/valueList.size();
        }
        this.singleValue = map;
        this.mutiValue = Math.round(value*1000)*0.001d;
        this.level = levelRes;
    }
}